package com.sew.sewweb.common.utils;

import com.sew.sewweb.common.config.BaseConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jdom2.input.DOMBuilder;
import org.jdom2.output.XMLOutputter;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

/**
 * 发送XML到u8c
 */
@Slf4j
public class XMLSender {


    /**
     *  新增报文
     * @param mainRoot 个位置节点名称
     * @param rootAttribute 最外层根节点属性
     * @param id 第二层节点id值
     * @param mainMap 主表信息
     * @param subMapList 子表信息
     * @return
     * @throws Exception
     */
    public static ObjectNode add(Map<Integer,String> mainRoot,Map<String,String> rootAttribute,String id, Map<String, String> mainMap, List<Map<String, String>> subMapList) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = dbf.newDocumentBuilder();
        Document doc = builder.newDocument();
        //第一层根节点
        Element root = doc.createElement(mainRoot.get(0));
        //第一层根节点属性
        if(!rootAttribute.isEmpty()){
            Set set = rootAttribute.keySet();
            for(Object obj: set){
                root.setAttribute(obj.toString(), rootAttribute.get(obj.toString()));
            }
        }
        // 第二层根节点
        Element bill = doc.createElement(mainRoot.get(1));
        bill.setAttribute("id", id);
        // 第三层根节点
        Element billhead = doc.createElement(mainRoot.get(2));
        // 里层节点
        //生成xml
        List<String> list = new ArrayList<>(mainMap.keySet());
        list.sort(String::compareTo);
        for (String s : list) {
            if (!StringUtils.isBlank(mainMap.get(s))) {
                Element element = doc.createElement(s);
                element.setTextContent(mainMap.get(s));
                billhead.appendChild(element);
            }
        }
        //子表
        if(subMapList.size() > 0 && !subMapList.isEmpty()){
            Element element = doc.createElement(mainRoot.get(3));
            for (Map<String, String> subMap : subMapList) {
                Element item = doc.createElement(mainRoot.get(4));
                List<String> subList = new ArrayList<>(subMap.keySet());
                subList.sort(String::compareTo);
                for (String s : subList) {
                    if (!StringUtils.isBlank(subMap.get(s))) {
                        Element element1 = doc.createElement(s);
                        element1.setTextContent(subMap.get(s));
                        item.appendChild(element1);
                    }
                }
                element.appendChild(item);
                billhead.appendChild(element);
            }
        }

        bill.appendChild(billhead);
        root.appendChild(bill);
        doc.appendChild(root);
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        StringWriter stringWriter = new StringWriter();
        transformer.transform(new DOMSource(doc), new StreamResult(stringWriter));
        log.info("发送XML");
        log.info(stringWriter.toString());
        //webservice地址
        String url = BaseConfig.getConfig().getString("webServiceUrl");
        URL realURL = new URL(url);
        HttpURLConnection connection = (HttpURLConnection) realURL.openConnection();
        connection.setDoOutput(true);
        connection.setRequestProperty("content-type", "text/xml; charset=utf-8");
        connection.setRequestMethod("POST");
        // 设定格式
        XMLOutputter out = new XMLOutputter();
        log.error("发送数据到:" + url);
        out.output(new DOMBuilder().build(doc), connection.getOutputStream());
        InputStream inputStream = connection.getInputStream();
        Document parse = builder.parse(inputStream);
        Element documentElement = parse.getDocumentElement();
        NodeList sendresult = documentElement.getElementsByTagName("sendresult");
        Node item = sendresult.item(0);
        NodeList childNodes = item.getChildNodes();
        ObjectMapper om = new ObjectMapper();
        ObjectNode objectNode = om.createObjectNode();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node item1 = childNodes.item(i);
            if (item1.getNodeType() == 3) {
                continue;
            }
            log.info(item1.getTextContent().trim());
            objectNode.put(item1.getNodeName(), item1.getTextContent().trim());
        }
        log.info("生成json:{}", objectNode);
        return objectNode;
    }


    /**
     *  减少报文
     * @param mainRoot 个位置节点名称
     * @param rootAttribute 最外层根节点属性
     * @param id 第二层节点id值
     * @param mainMap 主表信息
     * @return
     * @throws Exception
     */
    public static ObjectNode reduce(Map<Integer,String> mainRoot,Map<String,String> rootAttribute,String id, Map<String, String> mainMap) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = dbf.newDocumentBuilder();
        Document doc = builder.newDocument();
        //第一层根节点
        Element root = doc.createElement(mainRoot.get(0));
        //第一层根节点属性
        if(!rootAttribute.isEmpty()){
            Set set = rootAttribute.keySet();
            for(Object obj: set){
                root.setAttribute(obj.toString(), rootAttribute.get(obj.toString()));
            }
        }
        // 第二层根节点
        Element bill = doc.createElement(mainRoot.get(1));
        bill.setAttribute("id", id);
        // 第三层根节点
        Element billhead = doc.createElement(mainRoot.get(2));
        // 里层节点
        //生成xml
        List<String> list = new ArrayList<>(mainMap.keySet());
        list.sort(String::compareTo);
        for (String s : list) {
            Element element = doc.createElement(s);
            element.setTextContent(mainMap.get(s));
            billhead.appendChild(element);
//            if (!StringUtils.isBlank(mainMap.get(s))) {
//
//            }
        }
        bill.appendChild(billhead);
        root.appendChild(bill);
        doc.appendChild(root);
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        StringWriter stringWriter = new StringWriter();
        transformer.transform(new DOMSource(doc), new StreamResult(stringWriter));
        log.info("发送XML");
        log.info(stringWriter.toString());
        //webservice地址
        String url = BaseConfig.getConfig().getString("webServiceUrl");
        URL realURL = new URL(url);
        HttpURLConnection connection = (HttpURLConnection) realURL.openConnection();
        connection.setDoOutput(true);
        connection.setRequestProperty("content-type", "text/xml; charset=utf-8");
        connection.setRequestMethod("POST");
        // 设定格式
        XMLOutputter out = new XMLOutputter();
        log.info("发送数据到:" + url);
        out.output(new DOMBuilder().build(doc), connection.getOutputStream());
        InputStream inputStream = connection.getInputStream();
        Document parse = builder.parse(inputStream);
        Element documentElement = parse.getDocumentElement();
        NodeList sendresult = documentElement.getElementsByTagName("sendresult");
        Node item = sendresult.item(0);
        NodeList childNodes = item.getChildNodes();
        ObjectMapper om = new ObjectMapper();
        ObjectNode objectNode = om.createObjectNode();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node item1 = childNodes.item(i);
            if (item1.getNodeType() == 3) {
                continue;
            }
            log.info(item1.getTextContent().trim());
            objectNode.put(item1.getNodeName(), item1.getTextContent().trim());
        }
        log.info("生成json:{}", objectNode);
        return objectNode;
    }

    /**
     *  变更报文
     * @param mainRoot 根节点名称
     * @param rootAttribute 最外层根节点属性
     * @param mainMap  内容
     * @return
     * @throws Exception
     */
    public static ObjectNode change(String mainRoot,Map<String,String> rootAttribute, Map<Integer, Document> mainMap) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = dbf.newDocumentBuilder();
        Document doc = builder.newDocument();
        //第一层根节点
        Element root = doc.createElement(mainRoot);
        //第一层根节点属性
        if(!rootAttribute.isEmpty()){
            Set set = rootAttribute.keySet();
            for(Object obj: set){
                root.setAttribute(obj.toString(), rootAttribute.get(obj.toString()));
            }
        }
        //生成xml
        List<Integer> list = new ArrayList<>(mainMap.keySet());
        list.sort(Integer::compareTo);
        for (Integer s : list) {
            //Document doc2 = builder.parse(new ByteArrayInputStream(mainMap.get(s).getBytes()));
            Node node = doc.importNode(mainMap.get(s).getDocumentElement(), true);
            root.appendChild(node);
        }
        doc.appendChild(root);
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        StringWriter stringWriter = new StringWriter();
        transformer.transform(new DOMSource(doc), new StreamResult(stringWriter));
        log.info("发送XML");
        log.info(stringWriter.toString());
        //webservice地址
        String url = BaseConfig.getConfig().getString("webServiceUrl");
        URL realURL = new URL(url);
        HttpURLConnection connection = (HttpURLConnection) realURL.openConnection();
        connection.setDoOutput(true);
        connection.setRequestProperty("content-type", "text/xml; charset=utf-8");
        connection.setRequestMethod("POST");
        // 设定格式
        XMLOutputter out = new XMLOutputter();
        log.info("发送数据到:" + url);
        out.output(new DOMBuilder().build(doc), connection.getOutputStream());
        InputStream inputStream = connection.getInputStream();
        Document parse = builder.parse(inputStream);
        Element documentElement = parse.getDocumentElement();
        NodeList sendresult = documentElement.getElementsByTagName("sendresult");
        Node item = sendresult.item(0);
        NodeList childNodes = item.getChildNodes();
        ObjectMapper om = new ObjectMapper();
        ObjectNode objectNode = om.createObjectNode();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node item1 = childNodes.item(i);
            if (item1.getNodeType() == 3) {
                continue;
            }
            log.info(item1.getTextContent().trim());
            objectNode.put(item1.getNodeName(), item1.getTextContent().trim());
        }
        log.info("生成json:{}", objectNode);
        return objectNode;
    }

    /**
     *
     * @param mainRoot  所有根节点集合
     * @param id  第一层根节点属性
     * @param mainMap 内容
     * @return
     * @throws Exception
     */
    public static Document detail(Map<Integer,String> mainRoot,String id,Map<String, String> mainMap) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = dbf.newDocumentBuilder();
        Document doc = builder.newDocument();
        //第一层根节点
        Element root = doc.createElement(mainRoot.get(0));
        root.setAttribute("id", id);
        // 第二层根节点
        Element bill = doc.createElement(mainRoot.get(1));
        //生成xml
        List<String> list = new ArrayList<>(mainMap.keySet());
        list.sort(String::compareTo);
        for (String s : list) {
            Element element = doc.createElement(s);
            element.setTextContent(mainMap.get(s));
            bill.appendChild(element);
//            if (!StringUtils.isBlank(mainMap.get(s))) {
//
//            }
        }
        root.appendChild(bill);
        doc.appendChild(root);
        //String xml = docToString(doc);
        return doc;
    }
    public static String docToString(Document doc) throws TransformerException {
        String docStr = "";
        if(doc!=null){
//            try{
//                TransformerFactory transformerFactory = TransformerFactory.newInstance();
//                Transformer transformer = transformerFactory.newTransformer();
//                transformer.setOutputProperty("encoding", "UTF8");
//                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//                transformer.transform(new DOMSource(doc), new StreamResult(outputStream));
//                //docStr = outputStream.toString();
//                docStr = outputStream.toString("UTF-8");
//                System.out.println("\n**********************     【org.w3c.dom.Document对象转XML字符串内容：】       **********************\n"+docStr);
//            }catch(Exception e){
//                e.printStackTrace();
//            }
            TransformerFactory transFactory = TransformerFactory.newInstance();
            Transformer transformer = transFactory.newTransformer();
            StringWriter buffer = new StringWriter();
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            transformer.transform(new DOMSource(doc),
                    new StreamResult(buffer));
            docStr = buffer.toString();
           log.info("【org.w3c.dom.Document对象转XML字符串内容：】\n" + docStr);
        }
        return docStr;
    }
}
